﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Threading;
using System.Xml.Linq;

namespace Jukebox
{
    /// <summary>
    /// This is the message interface abstraction
    /// </summary>
    interface Message
    {
        void Execute(State state);
    }
    /// <summary>
    /// This message will add a song to the jukebox
    /// </summary>
    public class AddSong : Message
    {
        Guid? Result { get; set; }
        SongData Song { get; set; }
        Semaphore mSemaphore;
        public AddSong(SongData song)
        {
            mSemaphore = new Semaphore(0, 1);
            Song = song;
        }
        public void Execute(State state)
        {
            Result = state.AddSong(Song);
            mSemaphore.Release();
        }
        public Guid? WaitForResult()
        {
            mSemaphore.WaitOne();
            mSemaphore.Dispose();
            return Result;
        }
    }
    /// <summary>
    /// This message will remove a song from the jukebox
    /// </summary>
    public class RemoveSong : Message
    {
        Guid Song { get; set; }
        public RemoveSong(Guid id)
        {
            Song = id;
        }
        public void Execute(State state)
        {
            state.CancelSong(Song);
        }
    }
    /// <summary>
    /// This will add a commercial to the jukebox
    /// </summary>
    public class AddCommercial : Message
    {
        CommercialData Commercial { get; set; }
        public AddCommercial(CommercialData commercial)
        {
            Commercial = commercial;
        }
        public void Execute(State state)
        {
            state.AddCommercial(Commercial);
        }
    }
    /// <summary>
    /// This will cancel any running commercial
    /// </summary>
    public class CancelCommercial : Message
    {
        public CancelCommercial()
        {
        }
        public void Execute(State state)
        {
            state.CancelCommercial();
        }
    }
    /// <summary>
    /// This will obtain the playlist from the jukebox
    /// </summary>
    public class GetPlaylist : Message
    {
        XElement Result { get; set; }
        Semaphore mSemaphore;
        public GetPlaylist()
        {
            mSemaphore = new Semaphore(0, 1);
        }
        public void Execute(State state)
        {
            Result = state.GetPlaylist();
            mSemaphore.Release();
        }
        public XElement WaitForResult()
        {
            mSemaphore.WaitOne();
            mSemaphore.Dispose();
            return Result;
        }
    }
    /// <summary>
    /// This will terminate the jukebox
    /// </summary>
    public class Stop : Message
    {
        public void Execute(State state)
        {
            state.Stop();
        }
    }
}